/*******************************************************************************
  MPLAB Harmony Application Source File

  Company:
    Microchip Technology Inc.

  File Name:
    app.c

  Summary:
    This file contains the source code for the MPLAB Harmony application.

  Description:
    This file contains the source code for the MPLAB Harmony application.  It
    implements the logic of the application's state machine and it may call
    API routines of other MPLAB Harmony modules in the system, such as drivers,
    system services, and middleware.  However, it does not call any of the
    system interfaces (such as the "Initialize" and "Tasks" functions) of any of
    the modules in the system or make any assumptions about when those functions
    are called.  That is the responsibility of the configuration-specific system
    files.
 *******************************************************************************/

// *****************************************************************************
// *****************************************************************************
// Section: Included Files
// *****************************************************************************
// *****************************************************************************

#include "app.h"
#include "definitions.h"    //必須      

#include "stdio.h"
#include "1lcd_lib_XC32.h"
#include "lcd_ACM1602_lib_i2c.h"
#include "INT070_Touch_lib_XC32.h"


int delay_Clock = 200000000;   //システムクロック：200MHz
char Buf[64];
bool WideUseMojuleBoard;    //汎用モジュール評価ボードが接続されている場合：1

int adcX,adcY;  //タッチ座標x,y
int cTouched;   //タッチ発生で1
int prevTouched;    //一巡前の　タッチ発生で '1'、　タッチ無なら '0'
int prev_abcX, prev_abcY;   //1サイクル前のタッチ座標x,y

SYS_TIME_HANDLE StringChange_handle;   //Scr1 タイトル文字切り替えタイマ
int ScreenNum;  //スクリーン番号
int Mode1;  //初期画面の表示文字列モード
int OneShotFlag_Scr0NextBtn;

extern SYS_TIME_HANDLE PictureCycle_handle;
extern int OneShotFlag_Scr1NextBtn; //ボタン誤動作防止ワンショットタイマフラグ


void delay_us(volatile unsigned int usec)        //1μsec遅延
{
        volatile  int count;
        count = (int)(delay_Clock/20000000)*usec;
        
        do      //実測　at　200MH (Clock=200000000)
        {       //delay_us(1000)：1000.4μsec  delay_us(100)：100.6μsec  delay_us(10):10.5μsec　　delay_us(1)：1.5μsec
                asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");asm("NOP");
                asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");

                count--;
        }while(count != 0);
}

void delay_ms(volatile unsigned int msec)        //1msec遅延
{
        volatile unsigned int i;         //実測：at200MH (Clock=200000000)//delay_ms(1)： 1.0006msec   delay_ms(100)：100.04msec

        for(i=0; i<msec; i++)
        delay_us(1000);
}


void All_LedOff(void)   //全LED消灯
{
    LATGbits.LATG15 = 0; //RG15: LED1消灯
    LATDbits.LATD4 = 0;  //RD4: LED2消灯
    LATAbits.LATA15 = 0;  //RA15: LED3消灯
    LATAbits.LATA14 = 0; //RA14: LED4消灯
}

void All_LedOn(void)    //全LED点灯
{
    LATGbits.LATG15 = 1;    //RG15: LED1点灯
    LATDbits.LATD4 = 1;     //RD4: LED2点灯
    LATAbits.LATA15 = 1;    //RA15: LED3点灯
    LATAbits.LATA14 = 1;    //RA14: LED4点灯
}



void StringChange ( uintptr_t context )     //システムタイマ(CoreTimer)から
                                                       //2000msec毎のコールバック（割り込み）発生
{
    if(Mode1 == false)    
    {
        Mode1 = true;
        //初期画面(Screen0)のラベル文字列を表示： <Harmony Ver.3>、LCD INT035、by Legato
        Screen0_LabelWidget0->fn->setString(Screen0_LabelWidget0, (leString*)&string_Harmony_Ver3);
        Screen0_LabelWidget1->fn->setString(Screen0_LabelWidget1, (leString*)&string_Touch_LCD_INT070);
        Screen0_LabelWidget2->fn->setString(Screen0_LabelWidget2, (leString*)&string_by_Legato);
        
        lcd_cmd(0x80);          //1目の先頭へ
        sprintf(Buf,"4bit parallel     ");//
        lcd_str(Buf);                   //液晶表示
        lcd_cmd(0xC0);          //２行目の先頭へ
        sprintf(Buf,"   control LCD    ");	//
        lcd_str(Buf);           // 開始メッセージ1行目表示
        
        if(WideUseMojuleBoard == true)
        {
            lcd_ACM1602_cmd_i2c(0x80);  //1行目の先頭へ
            lcd_ACM1602_str_i2c("I2C control       ");
            lcd_ACM1602_cmd_i2c(0xC0);  //2行目の先頭へ
            lcd_ACM1602_str_i2c("          LCD             ");
        
            All_LedOff();    //全LED消灯
        }
    }
    else 
    {
        Mode1 = false;
        //初期画面(Screen0)のラベル文字列を表示： Welcome to、PIC32MZ、Evaluation Board
        Screen0_LabelWidget0->fn->setString(Screen0_LabelWidget0, (leString*)&string_Welcome_to);
        Screen0_LabelWidget1->fn->setString(Screen0_LabelWidget1, (leString*)&string_PIC32MZ_Evaluation_Board);
        Screen0_LabelWidget2->fn->setString(Screen0_LabelWidget2, (leString*)&string_INT070_inchi7_0_800x480pixel);
        
        lcd_cmd(0x80);          //1目の先頭へ
        sprintf(Buf,"Touch Position   ");//
        lcd_str(Buf);                   //液晶表示
        lcd_cmd(0xC0);          //２行目の先頭へ
        sprintf(Buf,"    (X,Y)        ");	//
        lcd_str(Buf);           // 開始メッセージ1行目表示
        
        if(WideUseMojuleBoard == true)
        {   
            lcd_ACM1602_cmd_i2c(0x80);  //1行目の先頭へ
            lcd_ACM1602_str_i2c("Welcome to            ");
            lcd_ACM1602_cmd_i2c(0xC0);  //2行目の先頭へ
            lcd_ACM1602_str_i2c("    PIC32MZ          ");
        
            All_LedOn();    //全LED点灯
               
        }
    }
}

     
void ys_DRV_TOUCH_INT070(void)    //MSP2807タッチ検出  //タッチ検出、タッチ種類、タッチ位置とシステムに注入
{
    cTouched = INT070_TouchDetect();        //タッチ検出で　'1'     //Position detedted
    adcX = ys_TouchGetX();  //タッチ位置のx座標
    adcY = ys_TouchGetY();  //タッチ位置のy座標
   
     if((prevTouched == 0) && (cTouched == 1)) // Touch: Pressed
     {
         SYS_INP_InjectTouchDown(0,adcX,adcY);  //Touch:Pressed をシステムに注入
     }
    
     if(prevTouched == 1)   //一巡前のタッチが有った場合
     {
        if(cTouched == 1)                 // Touch: Moved
        {
            SYS_INP_InjectTouchMove(1,adcX,adcY);   //Touch:Movedをシステムに注入
        }
        else                        //Touch: Released
        {
            SYS_INP_InjectTouchUp(0,prev_abcX,prev_abcY);     //touch:Upをシステムに注入
        }
     }
    
    ////前回の値を保持
     prevTouched = cTouched;       
     prev_abcX = adcX;
     prev_abcX = adcY; 
     
    //タッチ位置座標のキャラクタ液晶への表示 
     	if(cTouched)    //タッチ有無判定			
		{
            if(adcX<800 && adcY<480) //座標表示範囲: (0,0)-(800,480)の矩形を指定
			{
                    //キャラクタ液晶にタッチ位置座標を表示
                    lcd_cmd(0x80);          //1目の先頭へ
                    sprintf(Buf,"Touch Position             \r\n");//
                    //sprintf(Buf,"cTouched=%d              \r\n",cTouched);//
                    lcd_str(Buf);                   //液晶表示
                   
                    lcd_cmd(0xC0);          //２行目の先頭へ
                    sprintf(Buf,"X=%d, Y=%d                 \r\n",adcX, adcY);	//
                    lcd_str(Buf);           // 開始メッセージ1行目表示
            }
		}else     	
        { 
            delay_ms(10);
        } 
}


// *****************************************************************************
// *****************************************************************************
// Section: Global Data Definitions
// *****************************************************************************
// *****************************************************************************

// *****************************************************************************
/* Application Data

  Summary:
    Holds application data

  Description:
    This structure holds the application's data.

  Remarks:
    This structure should be initialized by the APP_Initialize function.

    Application strings and buffers are be defined outside this structure.
*/

APP_DATA appData;

// *****************************************************************************
// *****************************************************************************
// Section: Application Callback Functions
// *****************************************************************************
// *****************************************************************************

/* TODO:  Add any necessary callback functions.
*/

// *****************************************************************************
// *****************************************************************************
// Section: Application Local Functions
// *****************************************************************************
// *****************************************************************************


/* TODO:  Add any necessary local functions.
*/


// *****************************************************************************
// *****************************************************************************
// Section: Application Initialization and State Machine Functions
// *****************************************************************************
// *****************************************************************************

/*******************************************************************************
  Function:
    void APP_Initialize ( void )

  Remarks:
    See prototype in app.h.
 */

void APP_Initialize ( void )
{
    /* Place the App state machine in its initial state. */
    appData.state = APP_STATE_INIT;



    /* TODO: Initialize your application's state machine and other
     * parameters.
     */
    ys_TouchHardwareInit(); //タッチ初期化 
    
       	
    lcd_init();				// LCD初期化
    lcd_cmd(0b00001100);    // カーソル:OFF  ブﾘﾝｸ:OFF        
    lcd_clear(); 
    
    lcd_cmd(0x80);          //1目の先頭へ
    sprintf(Buf,"PIC32MZ2048-     ");//
    lcd_str(Buf);                   //液晶表示
    lcd_cmd(0xC0);          //２行目の先頭へ
    sprintf(Buf,"   EFH100 booted");	//
    lcd_str(Buf);           // 開始メッセージ1行目表示
    
   EBIMSK0 = 0x28;         //必須　gfx:OK I2C2:OK   //SRAM 8MB用として、EBICS0なしモードでEBIを動作させる 
    
    
// 汎用モジュール評価ボード（段積みボード）の接続有無チェック  
    I2C2CONbits.ON = 0;      //IC2モジュール：OFF
    TRISAbits.TRISA2 = 1;
    TRISAbits.TRISA3 = 1;
    
    if((PORTAbits.RA2 == 0) || (PORTAbits.RA3 == 0))
    {
        WideUseMojuleBoard = false; //汎用モジュール評価ボード（段積みボード）は接続されていない。
        lcd_cmd(0x80);          //1目の先頭へ
        sprintf(Buf," I2C LCD is      ");//
        lcd_str(Buf);                   //液晶表示

        lcd_cmd(0xC0);          //２行目の先頭へ
        sprintf(Buf,"  NOT availabe   ");	//
        lcd_str(Buf);           // 開始メッセージ1行目表示
        
        delay_ms(2000);  
        
    }
    else
    {
        WideUseMojuleBoard = true;   //汎用モジュール評価ボード（段積みボード）は接続されている。
        
        I2C2CONbits.ON = 1;      //IC2モジュール：ON
        
        lcd_ACM1602_init_i2c();     //I2Cインターフェース式液晶初期化
        lcd_ACM1602_cmd_i2c(0x0C);    //カーソル：0FF、ブリンク：0FF
        
        lcd_ACM1602_cmd_i2c(0x80);  //1行目の先頭へ
        lcd_ACM1602_str_i2c("Harmony Ver.3           ");
        lcd_ACM1602_cmd_i2c(0xC0);  //2行目の先頭へ
        lcd_ACM1602_str_i2c(" Legato Start !!        ");
   }
}


/******************************************************************************
  Function:
    void APP_Tasks ( void )

  Remarks:
    See prototype in app.h.
 */

void APP_Tasks ( void )
{

    /* Check the application's current state. */
    switch ( appData.state )
    {
        /* Application's initial state. */
        case APP_STATE_INIT:
        {
            bool appInitialized = true;


            if (appInitialized)
            {
                StringChange_handle = SYS_TIME_CallbackRegisterMS(StringChange, 0, 2000, SYS_TIME_PERIODIC);  
                                                    //2000msec毎にsystemTimer_Callback関数を呼び出すように設定

                appData.state = APP_STATE_SERVICE_TASKS;
            }
            break;
        }

        case APP_STATE_SERVICE_TASKS:
        {
             //図形サイクルに於ける、任意の液晶画面タッチ検出    //
            if((cTouched == 1) &&
               (OneShotFlag_Scr1NextBtn == 0) && (OneShotFlag_Scr0NextBtn == 0) &&  //SWチャタリング防止
               ((ScreenNum == 2) || (ScreenNum == 3) || (ScreenNum == 4) || (ScreenNum == 5)))
            {
                SYS_TIME_TimerStop(PictureCycle_handle);    //図形サイクル用タイマ停止
               legato_showScreen(screenID_Screen0); //TOP画面へ戻る 
                ScreenNum = 0;
                SYS_TIME_TimerStart(StringChange_handle);
                Mode1 = 1;
                All_LedOff();    //全LED消灯
                SYS_TIME_TimerDestroy(PictureCycle_handle);
                if(WideUseMojuleBoard == true)  //汎用モジュール評価ボード（段積みボード)の接続有
                {
                    lcd_ACM1602_cmd_i2c(0x80);  //1行目の先頭へ
                    lcd_ACM1602_str_i2c("                  ");
                    lcd_ACM1602_cmd_i2c(0xC0);  //2行目の先頭へ
                    lcd_ACM1602_str_i2c("                  ");
                }
            }
            break;
        }

        /* TODO: implement your application state machine.*/


        /* The default state should never be executed. */
        default:
        {
            /* TODO: Handle error in application's state machine. */
            break;
        }
    }
}


/*******************************************************************************
 End of File
 */
